import os
import sys
import numpy
import shutil

class index():
	"""Indexes certain files in a given base directory"""
	types = []
	files = []
	newpath = ""
	indexpath = ""
	existingpath = ""
	randtrack = []
	treesize = 0

	def __init__(self,types,existpath,path,indexpath):
		"""Initialise the class"""
		self.types = types
		self.newpath = os.path.abspath(path)
		self.indexpath = os.path.abspath(indexpath)
		self.existingpath = existpath		
	
	def createBaseDir(self):
		self.createDir(self.newpath)

	def createDir(self,path):
		#CHECK IF PATH EXISTS, IF NOT CREATE IT
		if os.path.isdir(path) != 1:
			try:				
				os.mkdir(path)
			except:
				print "Could not create directory: %s" % path
				print "Exiting Gracefully!"
				sys.exit()
#		else:
#			print "Directory Exists %s" % path

	def traverseDir(self,path):
		dirs = []
		a=0
		dir1 = path
		#READ ALL THE FILES IN THE BASE DIRECTORY
		try:
			for filename in os.listdir(dir1):
				#IF FILE THEN PRINT THE NAME
				if os.path.isfile(os.path.join(dir1,filename)):		
					for elem in self.types:	
						if os.path.splitext(filename)[1].lower()[1:] == elem.lower():
							self.files.append([os.path.join(dir1,filename),os.path.getsize(os.path.join(dir1,filename))])				
							self.treesize = self.treesize+os.path.getsize(os.path.join(dir1,filename))
				#IF DIRECTORY THEN ADD TO THE DIRECTORY LIST
				if os.path.isdir(os.path.join(dir1,filename)):
					dirs.append(filename)
#					print "New Directory: ",os.path.join(self.basedir,filename)		
			#CALL THE FUNCTION FOR ALL OF THE DIRECTORIES IN THE DIRECTORY LIST
			for direc in dirs:
				subdir = os.path.join(dir1,direc)
#				print "SubDir: ",subdir
				#CALL THE FUNCTION AGAIN FOR THE NEW SUBDIRECTORIES
				self.traverseDir(subdir)		
		except:
			print "Directory Could Not Be Opened: %s" % basedir
		
		return self.files

	def writeIndex(self):
		#OPEN FILE
		try:	
			f = file(self.indexpath,"w")		
		except:
			print "Could not create file! %s" % self.indexpath
			print "Exiting gracefully."
			sys.exit()		
		for elem in self.files:
			f.write(elem[0]+"\t"+str(elem[1])+"\n")
		f.close()

	def readIndex(self):
		#OPEN FILE
		try:
			f = file(self.indexpath,"r")
		except:
			print "Could not open file! %s" % self.indexpath
			print "Exiting gracefully."
			sys.exit()		
		for elem in f:
			elems = elem.strip("\n").split("\t")
			self.files.append([elems[0],int(elems[1])])
		f.close()
			 
 
	def selectRand(self,num):
		#CHECK NUMBER OF REQUESTED FILES IS LESS THAN TOTAL NUMBER
		if num < len(self.files)-1:	
			#CREATE ARRAY OF RANDOM NUMBERS
			rand = numpy.random.randint(0,len(self.files),num)
			rand_selection = []
			for val in rand:
				rand_selection.append(self.files[val][0])		
				self.randtrack.append(self.files[val][0])			
			print rand_selection
		else:
			print "Too many files selected"
			sys.exit()

	def copyRand(self):
		#FOR EVERY ELEMENT OF THE LIST CONTAINING
		#RANDOM TRACKS COPY THEM TO THE NEW DIRECTORY
		
		#WRITE M3U FILE FOR THESE
		#OPEN THE FILE AND WRITE ELEM
		try:
			l = os.path.join(self.newpath,"rand.m3u")
			f = file(l,"w")			
		except:
			print "Could not open file: %s" % os.path.join(self.newpath,"rand.m3u")
			print "Exiting Gracefully"
			sys.exit()

		#FIRST NEED TO SPLIT THE OLD BASE PATH
		for elem in self.randtrack:
			file1= elem.split(self.existingpath)[1]
			#SPLIT ALL DIRECTORIES AND THEN CREATE THEM
			dirs = file1.split(os.sep)[0:-1]	
			newdir = ""
			#LOOP THROUGH THE SUBDIRS AND CREATE THEM
			for elem1 in dirs:
				newdir = os.path.join(newdir,elem1)
				self.createDir(os.path.join(self.newpath,newdir))
				#COPY FILE
			#print elem, "\n",os.path.join(self.newpath,file)
			shutil.copyfile(elem,os.path.join(self.newpath,file1))
			#WRITE TO THE M3U
			#print os.path.join(self.newpath,file1)+"\n"				
			f.write(os.path.join(self.newpath,file1)+"\n")
		f.close()

	def selectSize(self,size,iterations):
		"""Allows selecting of a number of random files until
		the limit specified by size is reached
		
		The iterations variable is so that we constantly don't get
		stuck in a loop looking for a file below the size limit"""
		size = size*2**10*2**10		
		while iterations > 0:				
			index = numpy.random.randint(0,len(self.files))
			sizefile = self.files[index][1]
			#print self.files[index][0], sizefile
	
#			print size - sizefile
			if size - sizefile < 0:
				iterations = iterations - 1
			else:
				size = size - sizefile	
				self.randtrack.append(self.files[index][0])

if __name__ == '__main__':

	a = index(["mp3"],"/media/work_fat32/Music/","/media/work_fat32/Random_Music","index.txt")
	a.createBaseDir()
#	a.traverseDir(a.existingpath)
	#a.writeIndex()	
	a.readIndex()
	#select a random X
#	a.selectRand(10)
	a.selectSize(10,1000)
	a.copyRand()
